#ifndef XGE_XGE_COMMON_CONFIG_H_
#define XGE_XGE_COMMON_CONFIG_H_
#define _CRT_SECURE_NO_WARNINGS
#include "xge_common_config.h"
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#endif 
#include <tchar.h>
#include <yvals.h>
// Google stdint.h for windows VS
#include "msv/stdint.h"
#define XGE_USE_WIDE_CHAR 1
// We using this macro to control the use of wide char 
// when XGE_USE_WIDE_CHAR defined the whole 
#ifdef XGE_USE_WIDE_CHAR
typedef wchar_t char_t;
#define _xT(Str) _T(Str)
#define __X__FILE__ __FILEW__
#define __X__FUNC__ __FUNCTIONW__
#else
typedef char char_t;
#define _xT(Str) Str
#define __X__FILE__ __FILE__
#define __X__FUNC__ __FUNCTION__
#endif// XGE_USE_WIDE_CHAR

// Dummy arg macro to disable the warning of the compiler
#define DUMMY_ARG(Argument) __noop

// Disable the copy and assign operation of certain class
#define DISALLOW_COPY_AND_ASSIGN(ClassName) ClassName& operator=( const ClassName& ); \
  ClassName( const ClassName& )

// Explicit ctor
#define EXPLICIT_CTOR(ClassName,ArgumentList) explicit ClassName( ArgumentList )
#define FORCEINLINE __forceinline
#define FASTCALL __fastcall
#define GLOBAL_ENGINE_NAME _xT("XGameEngine")
#define X_SYS_LOG_FILE_NAME  GLOBAL_ENGINE_NAME _xT(".syslog.log" )

namespace xge{
  // LogLevel enumeration 
  const int   INFO = 1 ;
  const int   WARNING = 2 ;
  const int   PANIC = 3 ;
  const int   FATAL=4 ;

  static const char_t* kLogPrefix[] = {
    _xT("[NULL]:"),
    _xT("[INFO]:"),
    _xT("[WARNING]:"),
    _xT("[PANIC]:"),
    _xT("[FATAL]:")
  };
  static const char_t* kLogFileNamePrefix[]= {
    _xT("NULL"),
    _xT("INFO"),
    _xT("WARNING"),
    _xT("PANIC"),
    _xT("FATAL")
  };

  // Building file system register
  static const char_t* kLocalFileSystemName = _xT("Win32FileSystem");
  static const char_t* kZipFileSystemName   = _xT("ZipFileSystem");
  FORCEINLINE const char_t* GetZipFileSystemName()  {
    return kZipFileSystemName;
  }
  FORCEINLINE const char_t* GetLocalFileSystemName() {
    return kLocalFileSystemName;
  }
  // Render Device Type
  // The supported device type
  enum DeviceType {
    DEVICE_D3D8 , // D3D8 
    DEVICE_D3D9 , // D3D9
    DEVICE_OPENGL , // OpenGL
    DEVICE_DEFAULT  // Default Device (D3D8 always)
  };
  // Calling frequency
  enum CallingFrequency {
    FREQ_ALL            =5 , // this value is only used to query 

    FREQ_SYNCHRONIZATION=0 , // this node will be called in every frame
    FREQ_HIGH_USE       =1 , // this node will be called within 50ms
    FREQ_MID_USE        =2 , // this node will be called 0.2s(200ms)
    // a person
    FREQ_LOW_USE        =3 , // this node will be called every 500 ms( 0.5s)
    FREQ_RARE_USE       =4   // this node will only be called every 1 seconds (1000ms)
  };

  static const int CALLING_FREQUENCY_LENGTH = 5 ;

}// namespace xge

#define CHECK_LOG_LEVEL(Level) ((Level)>=INFO && (Level)<=FATAL)
// Some predefined buffer size
#define MAX_CHAR_STACK_BUFFER_SIZE 1024 // sizeof(char_t) so it may be 2K byte 
#define MAX_CHAR_HEAP_BUFFER_SIZE 4096 // sizeof(char_t) so it may be 8K byte
// Some exit code 
#define ASSERTION_EXIT_CODE 3
#define NORMAL_EXIT_CODE 1
#define ABNORMAL_EXIT_CODE 4


//=============================================================System Module Exit Routine Priority Definition========================================================//
// The priority is pretty important , the lower the priority , the later the AtExitCallback will be executed
// we manage the system resource in the XAtExitManager system callback 
// any other important resource will be located in other priority

// 1. Lowest priority level , this should be kept dummy 
#define XATEXIT_LOWEST_PRIORITY 1
// 2. Priority: XThreadManager
// Thread Manager should exit at last when whole system get the quit message
#define XTHREADMANAGER_DESTROY_PRIORITY XATEXIT_LOWEST_PRIORITY+1
// 3. Priority: XTaskManager
// This must be higher than the XTHREADMANAGER_DESTROY_PRIORITY
#define XTASKMANAGER_DESTROY_PRIORITY XTHREADMANAGER_DESTROY_PRIORITY+1
// 4. Priority: XPluggerManager
// Define the XPluggerManager priority
// This must be lower than any related module( like XFileSystemManager , XRenderSystemManager )
#define XPLUGGERMANAGER_DESTROY_PRIORITY XTASKMANAGER_DESTROY_PRIORITY+1   
// 5. Priority: XFileSystemManager
#define XFSMANAGER_DESTROY_PRIORITY XPLUGGERMANAGER_DESTROY_PRIORITY+1
// 6. Render Exit Priority
#define XRENDER_DESTROY_PRIORITY XFSMANAGER_DESTROY_PRIORITY+1

// Define the specific task type 
// Remote or Local
#define REMOTE_BINDING 0
#define LOCAL_BINDING  1
#define REMOTE_MESSAGE 2
#define LOCAL_MESSAGE  3

#define MIN_TASK_BINDING_VALUE REMOTE_BINDING
#define MAX_TASK_BINDING_VALUE LOCAL_MESSAGE

#endif // XGE_XGE_COMMON_CONFIG_H_